package paim.wingchun.testes;

import paim.wingchun.model.validadores.Validador;

public class TesteBrasil {

    public final static int MOD11_CASO_0 = 0;

    public final static int MOD11_CASO_1 = 1;

    public final static int MOD11_CASO_2 = 2;

    /**
     * Valida um numerico usando modulo 11. Considera que o ultimo caracter da string stEnt eh o DV a ser comparado com o valor
     * calculado usando os demais caracteres da string. Isto eh, na string de entrada 71973524791 (um CPF valido) o DV (1) eh
     * comparado com o calculo em cima da strig 7197352479 (que dara 1) e retornara true.
     * 
     * @param stEnt
     *            String que representa o numero a ser validado.
     * @param stMult
     *            String de multiplicacao desejada; se null, sera usado '... 12 11 10 98765432'.
     * @param inStatus
     *            O modulo 11 consiste na diferenca entre 11 e o resto da divisao de um somatorio por 11. Para os valores de
     *            retorno 10 (quanto o resto eh 1) ou 11 (resto 0), existem versoes com diferentes resultados; use as constantes
     *            MOD11_CASO_0, ..._1 e ..._2, conforme descrito abaixo, para especificar o retorno desejado para estas solucoes:<br>
     *            MOD11_CASO_0 : Usado no calculo de processos, retorna as saidas 10 e 11 sem nenhum tratamento.<br>
     *            MOD11_CASO_1 : usado no calculo de processos com data superior a 2000 e titulos de eleitor. Converte a saida 10
     *            em 0 e saida 11 em 1.<br>
     *            MOD11_CASO_2 : usado no calculo do CNPJ e CPF, converte ambas saidas 10 e 11 em 0.
     * @return boolean - true a string representa um modulo 11 valido.
     * @see Validador#calcularModulo11
     * @author Ricardo Caetano
     */
    public static boolean validarModulo11(String stEnt, String stMult, int inStatus) {
        String stDigVerif, stNumero;
        int inDigVerif, inDigVerifCalc;

        // Separa o numero para calcular o modulo 11
        stNumero = stEnt.substring(0, stEnt.length() - 1);
        inDigVerifCalc = calcularModulo11(stNumero, stMult, inStatus);

        // do digito verificador no proprio numero
        stDigVerif = stEnt.substring(stEnt.length() - 1, stEnt.length());
        inDigVerif = Integer.valueOf(stDigVerif).intValue();

        return (inDigVerifCalc == inDigVerif);
    }

    /**
     * Calcula e retorna o modulo 11 do numerico em stEnt.
     * 
     * @param stEnt
     *            Numerico do qual se deseja calcular o modulo 11.
     * @param stMult
     *            String de multiplicacao desejada; se stMult == null, sera usado '... 12 11 10 98765432'.
     * @param inStatus
     *            O modulo 11 consiste na diferenca entre 11 e o resto da divisao de um somatorio por 11. Para os valores de
     *            retorno 10 (quanto o resto eh 1) ou 11 (resto 0), existem versoes com diferentes resultados; use as constantes
     *            MOD11_CASO_0, ..._1 e ..._2, conforme descrito abaixo, para especificar o retorno desejado para estas solucoes:<br>
     *            MOD11_CASO_0 : Usado no calculo de processos, retorna as saidas 10 e 11 sem nenhum tratamento.<br>
     *            MOD11_CASO_1 : usado no calculo de processos com data superior a 2000 e titulos de eleitor. Converte a saida 10
     *            em 0 e saida 11 em 1.<br>
     *            MOD11_CASO_2 : usado no calculo do CNPJ e CPF, converte ambas saidas 10 e 11 em 0.
     * @return int - O digito modulo 11 do numerico de entrada (entre 0 e 11).
     * @author Ricardo Caetano
     */
    public static int calcularModulo11(String stEnt, String stMult, int inStatus) {
        int inMod11, inResto, inSoma = 0;

        // Verifica se eh para usar stMult ou gerar um multiplicador padrao
        if ( stMult == null ) {
            // Gerar
            for ( int i = 0; i < stEnt.length(); i++ ) {
                inSoma += ((stEnt.length() + 1 - i) * Character.getNumericValue(stEnt.charAt(i)));
            }
        }
        else {
            // Usar stMult
            for ( int i = 0; i < stEnt.length(); i++ ) {
                inSoma += (Character.getNumericValue(stMult.charAt(i)) * Character.getNumericValue(stEnt.charAt(i)));
            }
        }

        // Faz o modulo 11 da soma obtida acima
        inResto = inSoma - ((inSoma / 11) * 11);

        // O resto pode variar de 0 a 11; Os restos 0 e 1 geram inMod11
        // igual a 11 ou 10 - valores problema que tem diferentes tratamentos
        // conforme inStatus.
        inMod11 = 11 - inResto;

        // Trata casos especiais
        if ( inStatus == MOD11_CASO_2 ) {
            if ( inMod11 > 9 ) {
                // Se o resto eh 1 ou 0 => inMod11 = 10 ou 11.
                // Para MOD11_CASO_2, retorna zero nos dois casos
                inMod11 = 0;
            }
        }
        else if ( inStatus == MOD11_CASO_1 ) {
            if ( inMod11 == 10 ) {
                // Se o resto eh 1 => inMod11 = 10.
                // Para MOD11_CASO_1, retorna zero
                inMod11 = 0;
            }
            if ( inMod11 == 11 ) {
                // Se o resto eh 0 => inMod11 = 11.
                // Para MOD11_CASO_1, retorna um
                inMod11 = 1;
            }
        }

        // Para MOD11_CASO_0 o valor nao eh alterado
        return inMod11;
    }

    public static byte xxcpf(String stCPF) {
        // Testa o 1 DV
        if ( (!validarModulo11(stCPF.substring(0, 10), null, MOD11_CASO_2)) || // Testa o 2 DV
                (!validarModulo11(stCPF, null, MOD11_CASO_2)) ) {
            return 0;
        }
        return 0;
    }

    /* http://pt.wikipedia.org/wiki/D%C3%ADgito_verificador */
    @SuppressWarnings("unused")
    private static String getDVModulo11(String sNumero, byte nDV) {
               
        int idv = 0,  soma = 0;
        
        while ( nDV > 0  ) {
            for ( int i = 0; i < sNumero.length(); i++ ) {
                soma += Character.getNumericValue(sNumero.charAt(i)) * (sNumero.length() + 1 - i);
            }
            
            idv = (soma * 10) % 11;            
        }

        
        String.valueOf(idv);
        
        return "";
    }

    public static boolean isCnpjValido(String cnpj) {
        if ( !cnpj.substring(0, 1).equals("") ) {
            try {
                cnpj = cnpj.replace('.', ' ');// onde há ponto coloca espaço
                cnpj = cnpj.replace('/', ' ');// onde há barra coloca espaço
                cnpj = cnpj.replace('-', ' ');// onde há traço coloca espaço
                cnpj = cnpj.replaceAll(" ", "");// retira espaço
                int soma = 0, dig;
                String cnpj_calc = cnpj.substring(0, 12);

                if ( cnpj.length() != 14 ) {
                    return false;
                }
                char[] chr_cnpj = cnpj.toCharArray();
                /* Primeira parte */
                for ( int i = 0; i < 4; i++ ) {
                    if ( chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9 ) {
                        soma += (chr_cnpj[i] - 48) * (6 - (i + 1));
                    }
                }
                for ( int i = 0; i < 8; i++ ) {
                    if ( chr_cnpj[i + 4] - 48 >= 0 && chr_cnpj[i + 4] - 48 <= 9 ) {
                        soma += (chr_cnpj[i + 4] - 48) * (10 - (i + 1));
                    }
                }
                dig = 11 - (soma % 11);
                cnpj_calc += (dig == 10 || dig == 11) ? "0" : Integer.toString(dig);
                /* Segunda parte */
                soma = 0;
                for ( int i = 0; i < 5; i++ ) {
                    if ( chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9 ) {
                        soma += (chr_cnpj[i] - 48) * (7 - (i + 1));
                    }
                }
                for ( int i = 0; i < 8; i++ ) {
                    if ( chr_cnpj[i + 5] - 48 >= 0 && chr_cnpj[i + 5] - 48 <= 9 ) {
                        soma += (chr_cnpj[i + 5] - 48) * (10 - (i + 1));
                    }
                }
                dig = 11 - (soma % 11);
                cnpj_calc += (dig == 10 || dig == 11) ? "0" : Integer.toString(dig);
                return cnpj.equals(cnpj_calc);
            }
            catch ( Exception e ) {
                return false;
            }
        }
        else {
            return false;
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}
